package io.bdmc.modules.bss.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import io.bdmc.common.annotation.SysLogger1;
import io.bdmc.common.enums.RouteTypeEnum;
import io.bdmc.common.utils.Constant;
import io.bdmc.common.utils.Constant.ModifyName;
import io.bdmc.common.utils.R;
import io.bdmc.modules.bss.entity.*;
import io.bdmc.modules.bss.service.*;
import io.bdmc.modules.sys.controller.AbstractController;
import org.apache.commons.lang.SerializationUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.time.LocalDateTime;
import java.util.List;

/**
 * <p>
 * 设备通道与光纤芯序号对照表 前端控制器
 * </p>
 *
 * @author 黄露
 * @since 2020-08-14
 */

// "设备通道与光纤芯序号对照表", description = "设备通道与光纤芯序号对照表")
@RestController
@RequestMapping("/bss/device/fibre")
public class DeviceFibreMatchController extends AbstractController {

    @Autowired
    IDeviceFibreMatchService _matchServce;

    @Autowired
    IDeviceDeviceService deviceService;

    @Autowired
    IDeviceMachineOsModuleService _osModuleService;

    @Autowired
    IDeviceMachineOsService _osService;

    @Autowired
    IDeviceRouteService _routeService;

    @Autowired
    IDeviceMeasureService _measureService;

    @Autowired
    IDeviceAlarmRealtimeService alarmRealtimeService;

    @SysLogger1(value = "绑定设备通道与光纤芯", entityType = DeviceFibreMatch.class, operationType = ModifyName.ADD)
    @PostMapping("/bind")
    // "绑定设备通道与光纤芯", notes = "绑定设备通道与光纤芯")
    public R bind(@RequestBody DeviceFibreMatch devFibreMatch) {
        return R.trueOrFalse(bindMatch(devFibreMatch));
    }

    // @SysLogger1(value = "批量绑定设备通道与光纤芯", entityType = DeviceFibreMatch.class,
    // operationType = ModifyName.ADD)
    @PostMapping("/binds")
    // "绑定设备通道与光纤芯", notes = "绑定设备通道与光纤芯")
    public R binds(@RequestBody List<DeviceFibreMatch> devFibreMatch) {
        for (DeviceFibreMatch deviceFibreMatch : devFibreMatch) {
            bindMatch(deviceFibreMatch);
        }
        return R.ok();
    }

    private boolean bindMatch(DeviceFibreMatch devFibreMatch) {
        DeviceFibreMatch dbExist = _matchServce.selectByDeviceSnAndChannel(devFibreMatch.getDeviceSn(),devFibreMatch.getChannel());
        if(dbExist==null){
            dbExist = _matchServce.selectByDeviceIdAndChannel(devFibreMatch.getDeviceId(),devFibreMatch.getChannel());
        }
        if (dbExist != null)
            dbExist.deleteById();
        DeviceDevice deviceDevice;
        if (StringUtils.isEmpty(devFibreMatch.getDeviceSn())) {
            deviceDevice = deviceService.getById(devFibreMatch.getDeviceId());
        } else {
            deviceDevice = deviceService.getDeviceBySn(devFibreMatch.getDeviceSn());
        }
        if (deviceDevice == null) {
            logger.error("未找到设备：id:" + devFibreMatch.getDeviceId() + ",sn:" + devFibreMatch.getDeviceSn());
            return false;
        }
        if(devFibreMatch.getDeviceId()==null||devFibreMatch.getDeviceId()<=0)
            devFibreMatch.setDeviceId(deviceDevice.getDeviceId());

        if(StringUtils.isEmpty(devFibreMatch.getDeviceSn()))
            devFibreMatch.setDeviceSn(deviceDevice.getDeviceSn());

        devFibreMatch.setCreateBy(getUser().getUsername());
        devFibreMatch.setDeviceName(deviceDevice.getDeviceName());
        devFibreMatch.setCreateTime(LocalDateTime.now());
        boolean b = devFibreMatch.insert();
        if (StringUtils.isNotEmpty(devFibreMatch.getTargetDeviceSn()) && devFibreMatch.getTargetDeviceChannel() != null
                && devFibreMatch.getTargetDeviceChannel() > 0) {
            DeviceDevice targetDeviceDevice = deviceService.getDeviceBySn(devFibreMatch.getTargetDeviceSn());
            boolean isFspRoute = false;
            if (devFibreMatch.getRouteId() != null && devFibreMatch.getRouteId() > 0) {
                DeviceRoute route = _routeService.getById(devFibreMatch.getRouteId());
                if (route != null && route.getRouteType().equals(RouteTypeEnum.fspRoute.name())) {
                    isFspRoute = true;
                }
            }
            // 非fsp路由 只能一个设备一个端口绑定，所以要删除之前的
            if (!isFspRoute) {
                _matchServce
                        .remove(new QueryWrapper<DeviceFibreMatch>().eq("device_sn", devFibreMatch.getTargetDeviceSn())
                                .eq("channel", devFibreMatch.getTargetDeviceChannel()));
            }

            DeviceFibreMatch copyMatch = (DeviceFibreMatch) SerializationUtils.clone(devFibreMatch);
            copyMatch.setDeviceFibreId(0);
            copyMatch.setDeviceSn(devFibreMatch.getTargetDeviceSn());
            copyMatch.setDeviceId(targetDeviceDevice.getDeviceId());
            copyMatch.setDeviceName(devFibreMatch.getTargetDeviceName());
            copyMatch.setChannel(devFibreMatch.getTargetDeviceChannel());
            copyMatch.setTargetDeviceSn(devFibreMatch.getDeviceSn());
            copyMatch.setTargetDeviceChannel(devFibreMatch.getChannel());
            copyMatch.setTargetDeviceName(devFibreMatch.getDeviceName());
            _matchServce.save(copyMatch);
        }
        return b;
    }

    @SysLogger1(value = "解除绑定设备通道", entityType = DeviceFibreMatch.class, operationType = ModifyName.UPDATE)
    @PostMapping("/unbind")
    // "解除绑定设备通道", notes = "解除绑定设备通道")
    public R unbind(@RequestBody DeviceFibreMatch devFibreMatch) {
        unbindMatch(devFibreMatch);
        return R.ok();
    }

    //@SysLogger1(value = "解除绑定ifms设备通道和光缆", entityType = DeviceFibreMatch.class, operationType = ModifyName.UPDATE)
    @PostMapping("/unbind_ifms")
    // "解除绑定设备通道", notes = "解除绑定设备通道")
    public R unbindIfms(@RequestBody DeviceFibreMatch devFibreMatch) {
        LambdaQueryWrapper<DeviceFibreMatch> w1=  Wrappers.lambdaQuery();
        w1.eq(DeviceFibreMatch::getDeviceId, devFibreMatch.getDeviceId());
        w1.eq(DeviceFibreMatch::getChannel, devFibreMatch.getChannel());
        boolean result = _matchServce.remove(w1);
        return R.trueOrFalse(result);
    }


    @PostMapping("/unbinds")
    // "解除绑定设备通道", notes = "解除绑定设备通道")
    public R unbinds(@RequestBody List<DeviceFibreMatch> devFibreMatchList) {
        for (DeviceFibreMatch deviceFibreMatch : devFibreMatchList) {
            unbindMatch(deviceFibreMatch);
        }
        return R.ok();
    }

    private void unbindMatch(DeviceFibreMatch devFibreMatch) {
        if (devFibreMatch.getRouteId() != null && devFibreMatch.getRouteId() > 0) {
            final DeviceRoute route = _routeService.getById(devFibreMatch.getRouteId());
            if (route != null) {
                QueryWrapper<DeviceMeasure> w1 = new QueryWrapper<DeviceMeasure>().eq("channel",
                        devFibreMatch.getChannel());
                if (route.getRouteType().equals("realTimeRoute")) {
                    w1.eq("device_sn", route.getFmsSn()).eq("channel", devFibreMatch.getChannel());
                    _measureService.remove(w1);
                } else if (route.getRouteType().equals("pollingRoute") || route.getRouteType().equals("offlineRoute")) {
                    w1.eq("device_sn", route.getOswSn()).eq("channel", devFibreMatch.getChannel());
                    _measureService.remove(w1);
                }
            }
        }
        if (StringUtils.isNotEmpty(devFibreMatch.getTargetDeviceSn())) {
            // 如果有双向绑定，先删对向绑定关系
            _matchServce.remove(new QueryWrapper<DeviceFibreMatch>().eq("target_device_sn", devFibreMatch.getDeviceSn())
                    .eq("target_device_channel", devFibreMatch.getChannel()));
        }
        // 删除绑定关系
        _matchServce.removeById(devFibreMatch.getDeviceFibreId());
    }

    @GetMapping("/listBind")
    public R bindMatch() {
        final List<DeviceFibreMatch> matchList = _matchServce.selectBindFibreMatch(getDeptId().intValue());
        return R.ok().putData(matchList);
    }

    @GetMapping("/match")
    // "程序绑定设备通道与光纤芯", notes = "程序绑定设备通道与光纤芯")
    public R fibre() {
        return R.ok().putData(_matchServce.ListMeasureDevice());
    }


    @GetMapping("/list")
    // "程序绑定设备通道与光纤芯", notes = "程序绑定设备通道与光纤芯")
    public R list(DeviceFibreMatch devFibreMatch) {
        // DeviceDevice device =
        // deviceService.getDeviceBySn(devFibreMatch.getDeviceSn());
        List<DeviceFibreMatch> matchList = _matchServce
                .list(new QueryWrapper<DeviceFibreMatch>().eq("device_sn", devFibreMatch.getDeviceSn()));

        String deviceSn = devFibreMatch.getDeviceSn();
        for (DeviceFibreMatch deviceFibreMatch : matchList) {
            if (deviceFibreMatch.getRouteId() != null) {
                DeviceRoute route = _routeService.getById(deviceFibreMatch.getRouteId());
                if (route != null && route.getRouteType().equals(RouteTypeEnum.fspRoute.name())) {
                    DeviceDevice otdr = deviceService.getDeviceBySn(deviceFibreMatch.getTargetDeviceSn());
                    if (otdr != null) {
                        List<DeviceAlarmRealtime> alarmRealtimeList = alarmRealtimeService
                                .list(new QueryWrapper<DeviceAlarmRealtime>().eq("device_sn", otdr.getDeviceSn())
                                        .eq("alarm_type_code", Constant.ALARM_Distance));
                        long count = alarmRealtimeList.stream().filter(r -> r.getDeviceId().equals(otdr.getDeviceId())
                                && r.getChannel().equals(deviceFibreMatch.getTargetDeviceChannel())).count();
                        if (count > 0)
                            deviceFibreMatch.setLengthAlarmFlag(true);
                        continue;
                    }
                }
            }
            List<DeviceAlarmRealtime> alarmRealtimeList1 = alarmRealtimeService.list(
                    new QueryWrapper<DeviceAlarmRealtime>().eq("device_sn", deviceSn).eq("alarm_type_code", "CH"));
            long count = alarmRealtimeList1.stream().filter(
                    r -> r.getDeviceSn().equals(deviceSn) && r.getChannel().equals(deviceFibreMatch.getChannel()))
                    .count();
            if (count > 0)
                deviceFibreMatch.setLengthAlarmFlag(true);

        }
        return R.ok().putData(matchList);
    }

    @GetMapping("/opmList")
    // "程序绑定设备通道与光纤芯", notes = "程序绑定设备通道与光纤芯")
    public R opmList(DeviceFibreMatch fibreMatchArgs) {
        final List<DeviceFibreMatch> deviceFibreMatchList = _matchServce.selectByDeviceSn(fibreMatchArgs.getDeviceSn());
        for (DeviceFibreMatch deviceFibreMatch : deviceFibreMatchList) {
            if (deviceFibreMatch.getDeviceType() == null || deviceFibreMatch.getTargetDeviceType() == null) {
                continue;
            }
            if (deviceFibreMatch.getDeviceType().equals("OPM") && deviceFibreMatch.getTargetDeviceType().equals("OS")) {
                final DeviceMachineOs os = _osService.selectLastOsData(deviceFibreMatch.getTargetDeviceSn());
                if (os != null) {
                    QueryWrapper<DeviceMachineOsModule> w1 = new QueryWrapper<>();
                    w1.eq("machine_os_id", os.getMachineOsId())
                            .eq("os_module_num", deviceFibreMatch.getTargetDeviceChannel()).last("limit 1");
                    final DeviceMachineOsModule osModule = _osModuleService.getOne(w1);
                    if (osModule != null) {
                        deviceFibreMatch.setLightPower(osModule.getLightPower());
                    }
                }
            }
        }
        return R.ok().putData(deviceFibreMatchList);
    }

    @PostMapping("/update")
    // "绑定设备通道与光纤芯", notes = "绑定设备通道与光纤芯")
    public R update(@RequestBody DeviceFibreMatch devFibreMatch) {
        DeviceFibreMatch dbMatch = _matchServce.getById(devFibreMatch.getDeviceFibreId());
        boolean b = false;
        if (dbMatch != null) {
            dbMatch.setNormalPadControl(devFibreMatch.getNormalPadControl());
            b = dbMatch.updateById();
        }
        return R.trueOrFalse(b);
    }
}